#include <iostream>
#include <ctime>
#include <unistd.h>
#include "Socket.hpp"
#include "Protocol.hpp"

using namespace socket_ns;

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        std::cerr << "Usage: " << argv[0] << "server_ip server_port" << std::endl;
        exit(0);
    }

    std::string server_ip = argv[1];
    uint16_t server_port = std::stoi(argv[2]);

    SockSPtr sock = std::make_shared<TcpSocket>();
    if (!sock->BuildClientSocket(server_ip, server_port))
    {
        std::cerr << "connect error" << std::endl;
        exit(1);
    }

    srand(time(nullptr) ^ getpid());
    const static std::string opers = "+-*/%?!";

    std::string packagestringstream;
    while (true)
    {
        int x = rand() % 10;
        usleep(x * 1000);
        int y = rand() % 10;
        usleep(x * y * 1000);
        char oper = opers[y % opers.size()];

        // 构建请求
        auto req = Factory::BuildRequestDafault();
        req->SetValue(x, y, oper);

        // 1.序列化
        std::string jsonstr;
        req->Serialize(&jsonstr);
        // 2.添加长度报头字段
        std::string reqstr = Encode(jsonstr);
        std::cout << "request string :\n" << reqstr << std::endl; 
        // 3.发送数据
        sock->Send(reqstr);
        while (true)
        {
            // 4.读取应答
            ssize_t n = sock->Recv(&packagestringstream);
            if (n < 0)
            {
                break;
            }
            //5.报文解析，提取报头和有效载荷
            std::string package = Decode(packagestringstream);
            if (package.empty())
            {
                continue;
            }
            //6.反序列化
            auto resp = Factory::BuildResponseDafault();
            resp->Deserialize(package);

            //7.打印结果
            resp->PrintResult();
            break;
        }
        sleep(1);
    }

    sock->Close();

    return 0;
}

